#include "DeadProxyPacketBuffer.h"

//Needs to be added to config
int GamePort = 7331;
//End Config

PacketBuffer::PacketBuffer()
{
    Crypt = new TibiaXTEA;
}

void PacketBuffer::SetBuffer(unsigned char * packet, int length)
{
    pos = 0;
    len = length;
    buffer = new unsigned char[length];
    memcpy(buffer, packet, length);
}

void PacketBuffer::NewBuffer(int length)
{
    pos = 0;
    len = length;
    buffer = new unsigned char[length];
}

int PacketBuffer::GetLength()
{
    return len;
}

int PacketBuffer::GetPos()
{
    return pos;
}

void PacketBuffer::SetPos(int p)
{
    pos = p;
}

void PacketBuffer::SetKey(unsigned char * XTEAkey)
{
    Crypt->SetKey((char*)XTEAkey);
}

PacketBuffer::~PacketBuffer()
{
    delete Crypt;
    delete[] buffer;
}

unsigned char * PacketBuffer::GetBuffer()
{
    return buffer;
}

void PacketBuffer::Encrypt()
{
    Crypt->Encrypt(buffer, len);
}

void PacketBuffer::Decrypt()
{
    Crypt->Decrypt(buffer, len);
}

unsigned char * PacketBuffer::GetCopy()
{
    unsigned char * ret = new unsigned char[len];
    memcpy(ret, buffer, len);
    return ret;
}

//Read Functions
unsigned char PacketBuffer::ReadChar()
{
    unsigned char ret;
    memcpy((void*)&ret, (void*)(buffer + pos), 1);
    pos += 1;
    return ret;
}

unsigned short PacketBuffer::ReadShort()
{
    unsigned short ret;
    memcpy((void*)&ret, (void*)(buffer + pos), 2);
    pos += 2;
    return ret;
}

unsigned int PacketBuffer::ReadInt()
{
    unsigned int ret;
    memcpy((void*)&ret, (void*)(buffer + pos), 4);
    pos += 4;
    return ret;
}

unsigned long PacketBuffer::ReadLong()
{
    unsigned long ret;
    memcpy((void*)&ret, (void*)(buffer + pos), 8);
    pos += 8;
    return ret;
}

unsigned char * PacketBuffer::ReadCharArray(int length)
{
    unsigned char * ret = new unsigned char[length];
    memcpy((void*)ret, (void*)(buffer + pos), length);
    pos += length;
    return ret;
}

char * PacketBuffer::ReadString()
{
    unsigned short length;
    memcpy(&length, (void*)(buffer + pos), 2);
    pos += 2;
    char * ret = new char[length+1];
    ret[length] = 0;
    memcpy((void*)ret, (void*)(buffer + pos), length);
    pos += length;
    return ret;
}

Position PacketBuffer::ReadPos()
{
    Position ret;
    memcpy((void*)&ret, (void*)(buffer + pos), 5);
    pos += 5;
    return ret;
}
    
//Peek Functions
unsigned char PacketBuffer::PeekChar()
{
    unsigned char ret;
    memcpy((void*)&ret, (void*)(buffer + pos), 1);
    return ret;
}

unsigned short PacketBuffer::PeekShort()
{
    unsigned short ret;
    memcpy((void*)&ret, (void*)(buffer + pos), 2);
    return ret;
}

unsigned int PacketBuffer::PeekInt()
{
    unsigned int ret;
    memcpy((void*)&ret, (void*)(buffer + pos), 4);
    return ret;
}

unsigned long PacketBuffer::PeekLong()
{
    unsigned long ret;
    memcpy((void*)&ret, (void*)(buffer + pos), 8);
    return ret;
}

unsigned char * PacketBuffer::PeekCharArray(int length)
{
    unsigned char * ret = new unsigned char[length];
    memcpy((void*)ret, (void*)(buffer + pos), length);
    return ret;
}

char * PacketBuffer::PeekString()
{
    unsigned short length;
    memcpy(&length, (void*)(buffer + pos), 2);
    pos += 2;
    char * ret = new char[length+1];
    ret[length] = 0;
    memcpy((void*)ret, (void*)(buffer + pos), length);
    pos -= 2;
    return ret;
}

Position PacketBuffer::PeekPos()
{
    Position ret;
    memcpy((void*)&ret, (void*)(buffer + pos), 5);
    return ret;
}

//Unread Functions
void PacketBuffer::UnreadChar(unsigned char write)
{
    pos -= 1;
    memcpy((void*)(buffer + pos), (void*)&write, 1);
}

void PacketBuffer::UnreadShort(unsigned short write)
{
    pos -= 2;
    memcpy((void*)(buffer + pos), (void*)&write, 2);
}

void PacketBuffer::UnreadInt(unsigned int write)
{
   pos -= 4;
    memcpy((void*)(buffer + pos), (void*)&write, 4);
}

void PacketBuffer::UnreadLong(unsigned long write)
{
    pos -= 8;
    memcpy((void*)(buffer + pos), (void*)&write, 8);
}

void PacketBuffer::UnreadCharArray(unsigned char * write, int length)
{
    pos -= length;
    memcpy((void*)(buffer + pos), (void*)write, length);
}

//Unpeek Functions
void PacketBuffer::UnpeekChar(unsigned char write)
{
    memcpy((void*)(buffer + pos - 1), (void*)&write, 1);
}

void PacketBuffer::UnpeekShort(unsigned short write)
{
    memcpy((void*)(buffer + pos - 2), (void*)&write, 2);
}

void PacketBuffer::UnpeekInt(unsigned int write)
{
    memcpy((void*)(buffer + pos - 4), (void*)&write, 4);
}

void PacketBuffer::UnpeekLong(unsigned long write)
{
    memcpy((void*)(buffer + pos - 8), (void*)&write, 8);
}

void PacketBuffer::UnpeekCharArray(unsigned char * write, int length)
{
    memcpy((void*)(buffer + pos - length), (void*)write, length);
}

//Write Functions
void PacketBuffer::WriteChar(unsigned char write)
{
    memcpy((void*)(buffer + pos), (void*)&write, 1);
    pos += 1;
}

void PacketBuffer::WriteShort(unsigned short write)
{
    memcpy((void*)(buffer + pos), (void*)&write, 2);
    pos += 2;
}

void PacketBuffer::WriteInt(unsigned int write)
{
    memcpy((void*)(buffer + pos), (void*)&write, 4);
    pos += 4;
}

void PacketBuffer::WriteLong(unsigned long write)
{
    memcpy((void*)(buffer + pos), (void*)&write, 8);
    pos += 8;
}

void PacketBuffer::WriteCharArray(unsigned char * write, int length)
{
    memcpy((void*)(buffer + pos), (void*)write, length);
    pos += length;
}

//Skip Functions
void PacketBuffer::SkipChar()
{
    pos += 1;
}

void PacketBuffer::SkipShort()
{
    pos += 2;
}

void PacketBuffer::SkipInt()
{
    pos += 4;
}

void PacketBuffer::SkipLong()
{
    pos += 8;
}

void PacketBuffer::Skip(int length)
{
    pos += length;
}

void PacketBuffer::SkipString()
{
    unsigned short length;
    memcpy(&length, (void*)(buffer + pos), 2);
    pos += length + 2;
}

//Unskip Functions
void PacketBuffer::UnskipChar()
{
    pos -= 1;
}

void PacketBuffer::UnskipShort()
{
    pos -= 2;
}

void PacketBuffer::UnskipInt()
{
    pos -= 4;
}

void PacketBuffer::UnskipLong()
{
    pos -= 8;
}

void PacketBuffer::Unskip(int length)
{
    pos -= length;
}

//Parsing Functions
int PacketBuffer::ParseLogin(CharacterList ** CharList)
{
    CharacterList * ret = new CharacterList;
    ret->length = 0;
    Skip(4);
    if(ReadChar() != 0x14)
    {
        return 1;
    } else {
        unsigned short WelcomeStringLength = ReadShort();
        Skip(WelcomeStringLength + 1);
        unsigned char NumberOfCharacters = ReadChar();
        ret->length = NumberOfCharacters;
        
        for(int i = 0; i < NumberOfCharacters; i++)
        {
            ret->CharList[i].name = ReadString();
            ret->CharList[i].world = ReadString();
            ret->CharList[i].IP = PeekInt();
            WriteInt(1 << 24 | 127); //This is 127.0.0.1 backwards
            ret->CharList[i].port = PeekShort();
            WriteShort(GamePort);
        }
        *CharList = ret;
    }
    return 0;
}
            
            
        
    
